﻿using BaseFramework;
using BaseFramework.Core;
using BaseFramework.DbConnectionProvider;
using LiteFramework.Contract;
using LiteFramework.Model;
using LiteFramework.Server.Component;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Hosting;

namespace LiteFramework.Server
{
    #region Enum

    /// <summary>
    /// 枚举：服务状态
    /// </summary>
    public enum ServerStatus
    {
        /// <summary>
        /// 服务正常运行
        /// </summary>
        [Description("服务正常运行")]
        Running = 0,
        /// <summary>
        /// 服务已停止
        /// </summary>
        [Description("服务已停止")]
        Stop = 1,
        /// <summary>
        /// 服务器证书已过期
        /// </summary>
        [Description("服务器证书已过期")]
        Expired = 2,
        /// <summary>
        /// 系统正在升级维护
        /// </summary>
        [Description("系统正在升级维护")]
        Maintaining = 3,
        /// <summary>
        /// 服务器故障
        /// </summary>
        [Description("服务器故障")]
        Error = 4,
    }

    /// <summary>
    /// 服务器类型
    /// </summary>
    public enum ServerMode
    {
        /// <summary>
        /// 单一
        /// </summary>
        Single = 0,
        /// <summary>
        /// 多元
        /// </summary>
        Multiple = 1,
    }

    #endregion

    public delegate  void ServerStart();
    public delegate void ServerStop();

    /// <summary>
    /// ServerApplication 的摘要说明。
    /// </summary>
    [Serializable]
    public sealed class ServerApplication
    {
        private const string USER_SESSION_KEY = "USER_SESSION";
        private const string USER_PRIME_TAG_KEY = "USER_PRIME_TAG";
        /// <summary>
        /// 应用程序身份安全标记
        /// </summary>
        private const string APPROLE_SECURITY_TOKEN = "A8A4BBFD-A742-442D-AE29-4D1452CD2523";
        /// <summary>
        /// 超级管理员身份安全标记
        /// </summary>
        private const string ADMIN_SECURITY_TOKEN = "E6D3055D60CC4CFF83C17A27C1720897";
        private const string IS_APPROLE_UNDERSTUDY_KEY = "IS_APPROLE_UNDERSTUDY";
        private const string IS_ADMIN_UNDERSTUDY_KEY = "IS_ADMIN_UNDERSTUDY";
        private const string SERVER_HANDLE_KEY = "SERVER_HANDLE_KEY";

        public static event ServerStart OnServerStart;
        public static event ServerStart OnServerStop;

        [ThreadStatic]
        private static HttpContext _context;

        private static ServerStatus _serverStatus = ServerStatus.Stop; // 服务器状态
        private static string _statusDesc = "服务器未启动"; // 服务器状态描述
        private static ServerApplication _current = new ServerApplication(); // 
        private static string _commonFolderPath = null; // 通用路径
        private static readonly User _approle = null; // 应用程序角色用户
        private static User a55ac0ea_admin = null; // 管理员角色。特意加前缀，避免直接调用
        private static object a55ac0ea_lock = new object();
        private static ILicense _license = null; // 授权接口
        private static string _serverHandle = null; // 服务器句柄

        private static User admin
        {
            get
            {
                if (a55ac0ea_admin == null)
                {
                    // 获取超级用户
                    lock (a55ac0ea_lock)
                    {
                        if (a55ac0ea_admin == null)
                        {
                            try
                            {
                                a55ac0ea_admin = PersistentEntityMediator<User>.FindOne(ServerApplication.DefaultConnectionProvider(), Expression.Eq("UserName", SystemResources.ADMINISTRATOR_NAME));
                            }
                            catch (Exception ex)
                            {
                                WriteLog("系统", LogType.Error, "未找到系统超级管理员", ex);
                            }
                        }
                    }
                }
                return a55ac0ea_admin;
            }
        }

        #region Options

        private static ServerMode _serverMode = ServerMode.Single; // 服务模式：单一、多元
        private static int _userQty = 5; // 授权连接的用户数量。

        #endregion

        private IFactory _factory = null; // 工厂接口
        private Castle.Core.Logging.ILogger _logger = null; // 系统日志

        private ApproleScope _approleScope = null;
        private AdminScope _adminScope = null;

        [SecurityPermissionAttribute(SecurityAction.Assert, ControlPrincipal = true)]
        static ServerApplication()
        {
            Company globalCompany = new Company(SystemResources.APPROLE_NAME, "全局");
            Organization globalOrganization = new Organization(globalCompany);
            globalOrganization.Id = 0;
            globalOrganization.ParentId = -1;
            globalOrganization.DocNo = SystemResources.APPROLE_NAME;
            globalOrganization.Name = "全局";
            globalOrganization.Special = true;
            globalOrganization.Active = true;
            globalOrganization.InternalBag.SetValue("LeftFig", 0);
            globalOrganization.InternalBag.SetValue("RightFig", int.MaxValue);

            _approle = new User(SystemResources.APPROLE_NAME, "approle@mail.com");
            _approle.OrganizationIDs = new int[] { globalOrganization.Id };
            _approle.Organization = globalOrganization;
            _approle.InternalBag.SetValue("ID", 0);
            _approle.RealName = "APPROLE";
            _approle.Roles = new Role[0];

            _commonFolderPath = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "App_Data");
        }

        #region Public Property

        /// <summary>
        /// 是否已注册
        /// </summary>
        public static bool ProductLicensed
        {
            get
            {
                return (_license != null && _license.IsLicensed());
            }
        }

        /// <summary>
        /// 服务模式：单一 or 多元（针对公司）
        /// </summary>
        public static ServerMode ServerMode
        {
            get { return _serverMode; }
        }
        /// <summary>
        /// 授权连接的用户数量。服务模式＝Single时有效
        /// </summary>
        public static int UserQty
        {
            get { return _userQty; }
        }

        /// <summary>
        /// 服务器句柄
        /// </summary>
        public static string ServerHandle
        {
            get { return _serverHandle; }
        }

        /// <summary>
        /// 服务器状态
        /// </summary>
        public static ServerStatus ServerStatus
        {
            get { return _serverStatus; }
        }

        /// <summary>
        /// 服务器状态描述
        /// </summary>
        public static string StatusDesc
        {
            get { return _statusDesc; }
        }

        /// <summary>
        /// 组件工厂
        /// </summary>
        public static IFactory ComponentFactory
        {
            get
            {
                if (_current._factory != null)
                    return _current._factory;
                else
                    throw new BaseException("ServerApplication not initialize.");
            }
        }

        /// <summary>
        /// 日志记录器
        /// </summary>
        public static Castle.Core.Logging.ILogger Logger
        {
            get
            {
                if (_current._logger != null)
                    return _current._logger;
                else
                    return Castle.Core.Logging.NullLogger.Instance;
            }
        }

        /// <summary>
        /// 操作日志类型
        /// </summary>
        public enum LogType
        {
            /// <summary>
            /// 信息
            /// </summary>
            Info,
            /// <summary>
            /// 警告
            /// </summary>
            Warn,
            /// <summary>
            /// 错误
            /// </summary>
            Error,
            /// <summary>
            /// 严重错误
            /// </summary>
            Fatal
        }

        public static ServerApplication Current
        {
            get { return (IsInitialized() ? _current : null); }
        }

        /// <summary>
        /// 公用文件夹路径
        /// </summary>
        public static string CommonFolderPath
        {
            get
            {
                //return (IsInitialized() ? _commonFolderPath : null);
                return _commonFolderPath;
            }
            set { _commonFolderPath = value; }
        }

        /// <summary>
        /// 当前用户域专用文件夹
        /// </summary>
        public static string IsolatedFolderPath
        {
            get
            {
                string path = null;

                if (IsInitialized())
                {
                    path = Path.Combine(CommonFolderPath, (!String.IsNullOrEmpty(PrimeTag) ? PrimeTag : "Temp"));
                    if (!Directory.Exists(path))
                        Directory.CreateDirectory(path);
                }

                return path;
            }
        }

        /// <summary>
        /// 服务器缓存
        /// </summary>
        public static IReIsolatedCache Cache
        {
            get { return (IsInitialized() ? new ReIsolatedCache() : null); }
        }

        /// <summary>
        /// 请求上下文
        /// </summary>
        public static HttpContext Context
        {
            get
            {
                if (IsInitialized())
                {
                    if (HttpContext.Current != null)
                    {
                        return HttpContext.Current;
                    }
                    else
                    {
                        if (_context == null)
                        {
                            lock (_current)
                            {
                                if (_context == null)
                                {
                                    try
                                    {
                                        _context = new HttpContext(new System.Web.Hosting.SimpleWorkerRequest("default.html", String.Empty, new StringWriter()));
                                    }
                                    catch
                                    {
#warning 此处未处理异常问题
                                    }
                                }
                            }
                        }

                        return _context;
                    }
                }

                return null;
            }
        }

        public static ApplicationContext ApplicationContext { get { return ApplicationContext.Current; } }

        /// <summary>
        /// 当前实际登陆用户身份信息
        /// </summary>
        public User TrueUser
        {
            get
            {
                if (!IsSameHandle())
                    return null;

                //if (_approleScope != null)
                if (_approleScope != null && _approleScope.OriginalUser != null) //BY HYD
                    return _approleScope.OriginalUser;
                if (_adminScope != null && _adminScope.OriginalUser != null) //BY HYD
                    return _adminScope.OriginalUser;
                else
                    return User;
            }
        }

        /// <summary>
        /// 当前实际登陆用户身份信息
        /// </summary>
        public static UserNameChoice SimpleTrueUser
        {
            get { return User.ToChoice(Current.TrueUser); }
        }

        /// <summary>
        /// 实际用户网点
        /// </summary>
        public static Organization Organization
        {
            get { return Current != null && Current.TrueUser != null ? Current.TrueUser.Organization : null; }
        }

        /// <summary>
        /// 实际用户公司
        /// </summary>
        public static Company Company
        {
            get { return Organization != null ? Organization.Company : null; }
        }

        /// <summary>
        /// 当前请求上下文用户（可能不是当前实际登陆用户，TrueUser）
        /// </summary>
        public static User User
        {
            get
            {
                if (IsInitialized() && IsSameHandle())
                {
                    User user = GetContextUser();

                    if (user == null)
                    {
                        var comp = ServerApplication.ComponentFactory.Create<IPermissionContract>();
                        user = comp.GetUser();

                        if (user != null)
                        {
                            if (Context != null)
                                Context.User = user;
                            if (ApplicationContext != null)
                                ApplicationContext.User = user;
                            _current.SetSessionValue(USER_SESSION_KEY, user);
                        }
                    }

                    return user;
                }

                return null;
            }
        }

        /// <summary>
        /// 当前用户域标识
        /// </summary>
        public static string PrimeTag
        {
            get
            {
                if (IsInitialized())
                {
                    object obj = _current.GetSessionValue(USER_PRIME_TAG_KEY);
                    if (obj != null)
                    {
                        return (string)obj;
                    }
                    else
                    {
                        string primeTag = null;
                        string providerUserKey = null;

                        User user = GetContextUser();
                        if (user != null)
                        {
                            if (user.IsApprole && _current._approleScope != null)
                                primeTag = _current._approleScope.OriginalPrimeTag;
                            if (IsGlobleAdmin(user) && _current._adminScope != null)
                                primeTag = _current._adminScope.OriginalPrimeTag;
                            else
                                providerUserKey = user.ProviderUserKey;
                        }

                        if (String.IsNullOrEmpty(primeTag))
                        {
                            if (!String.IsNullOrEmpty(providerUserKey))
                            {
                                LogonComponent logonComp = (LogonComponent)ServerApplication.ComponentFactory.Create<ILogonContract>();

                                string securityToken;
                                logonComp.GetUserLoginInfo(providerUserKey, out securityToken, out primeTag);
                            }
                        }

                        if (String.IsNullOrEmpty(primeTag))
                        {
                            string[] names = ApplicationSetting.GetConnectionStringNames(false);
                            if (names.Length != 0)
                                primeTag = names[0];
                        }

                        _current.InitPrimeTag(primeTag);

                        return primeTag;
                    }
                }

                return null;
            }
        }

        #endregion

        #region public Function

        ///// <summary>
        ///// 初始化服务器
        ///// </summary>
        //public static void Initialize()
        //{
        //    Initialize(_commonFolderPath);
        //}

        ///// <summary>
        ///// 初始化服务器
        ///// </summary>
        ///// <param name="commonFolderPath"></param>
        //public static void Initialize(string commonFolderPath)
        //{
        //    LicenseUtility.Dispose();
        //    Initialize(_commonFolderPath, LicenseUtility.GetInstance());
        //}

        ///// <summary>
        ///// 初始化服务器
        ///// </summary>
        ///// <param name="commonFolderPath"></param>
        ///// <param name="serverHandle"></param>
        //public static void Initialize(string commonFolderPath, string serverHandle)
        //{
        //    LicenseUtility.Dispose();
        //    Initialize(_commonFolderPath, LicenseUtility.GetInstance(), serverHandle);
        //}

        /// <summary>
        /// 初始化服务器
        /// </summary>
        /// <param name="commonFolderPath"></param>
        /// <param name="license"></param>
        public static void Initialize(string commonFolderPath, ILicense license)
        {
            Initialize(commonFolderPath, license, Guid.NewGuid().ToString("N"));
        }

        /// <summary>
        /// 初始化服务器
        /// </summary>
        /// <param name="commonFolderPath"></param>
        /// <param name="license"></param>
        /// <param name="serverHandle"></param>
        public static void Initialize(string commonFolderPath, ILicense license, string serverHandle)
        {
            _commonFolderPath = commonFolderPath;

            //Assembly asm = Assembly.GetAssembly(typeof(ServerApplication));
            //if (!asm.GlobalAssemblyCache)   // 要求从 GAC 加载，以保证 Assembly 必需有强名称
            //{
            //    return;
            //}
            // License


            //LicenseUtility licenseUtility = LicenseUtility.GetInstance();

            //if ((licenseUtility.DateEnd - DateTime.Now).Days < 0)
            //{
            //    _serverStatus = ServerStatus.Expired;
            //    _statusDesc = "许可证书已过期，请联系软件提供商更新证书！";
            //    throw new PermissionException("许可证书已过期，请联系软件提供商更新证书！");
            //}
            //else
            //{
            //    _serverMode = licenseUtility.ServerMode;
            //    _userQty = licenseUtility.UserNumber;
            //}

            try
            {
                if (_current._factory == null)
                {
                    _current._factory = new ComponentFactory();
                }

                if (_current._logger == null)
                {
                    object obj = _current._factory.Create(typeof(Castle.Core.Logging.ILoggerFactory));
                    if (obj != null)
                    {
                        _current._logger = ((Castle.Core.Logging.ILoggerFactory)obj).Create("eventview");
                    }
                    else
                    {
                        _current._logger = Castle.Core.Logging.NullLogger.Instance;
                    }
                }

                _license = license;
                _serverHandle = serverHandle;
                _serverStatus = ServerStatus.Running;
                _statusDesc = "服务器正常运行！";

                if (OnServerStart != null)
                {
                    try
                    {
                        OnServerStart();
                    }
                    catch { }
                }
            }
            catch (Exception ex)
            {
                _serverStatus = ServerStatus.Error;
                _statusDesc = "服务器故障：" + ex.Message;
            }
        }

        #region Load License

        //此方法可获取远程的MAC地址
        [System.Runtime.InteropServices.DllImport("Iphlpapi.dll")]
        static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen);
        [System.Runtime.InteropServices.DllImport("Ws2_32.dll")]
        static extern Int32 inet_addr(string ipaddr);
        /// <summary>
        /// SendArp获取MAC地址
        /// </summary>
        /// <param name=&quot;RemoteIP&quot;>目标机器的IP地址如(192.168.1.1)</param>
        /// <returns>目标机器的mac 地址</returns>
        public static string getMacAddr_Remote(string RemoteIP)
        {
            System.Text.StringBuilder macAddress = new System.Text.StringBuilder();
            try
            {
                Int32 remote = inet_addr(RemoteIP);
                Int64 macInfo = new Int64();
                Int32 length = 6;
                SendARP(remote, 0, ref macInfo, ref length);
                string temp = Convert.ToString(macInfo, 16).PadLeft(12, '0').ToUpper();
                int x = 12;
                for (int i = 0; i < 6; i++)
                {
                    if (i == 5)
                    {
                        macAddress.Append(temp.Substring(x - 2, 2));
                    }
                    else
                    {
                        macAddress.Append(temp.Substring(x - 2, 2) + "-");
                    }
                    x -= 2;
                }
                return macAddress.ToString();
            }
            catch
            {
                return macAddress.ToString();
            }
        }

        #endregion

        /// <summary>
        /// 销毁服务
        /// </summary>
        public static void Destroy()
        {
            //if (Cache != null)
            //    Cache.Clear();

            //if (Context!=null && Context.Session != null)
            //    Context.Session.Clear();

            //if (Context!=null && Context.Application != null)
            //    Context.Application.Clear();

            /*
             * 以上不行，造成 _context 被不必要的创建 
             */

            try
            {
                IReIsolatedCache cache = Cache;
                if (cache != null)
                    cache.IsolatedClear();

                HttpContext context = HttpContext.Current;
                if (context != null)
                {
                    if (Context != null && context.Session != null)
                        context.Session.Clear();

                    if (Context != null && context.Application != null)
                        context.Application.Clear();
                }

                context = _context;
                if (context != null)
                {
                    if (Context != null && context.Session != null)
                        context.Session.Clear();

                    if (Context != null && context.Application != null)
                        context.Application.Clear();
                }

                if (_current._factory != null)
                {
                    _current._factory.Dispose();
                    _current._factory = null;
                }
            }
            finally
            {
                if (OnServerStop != null)
                {
                    try
                    {
                        OnServerStop();
                    }
                    catch { }
                }
            }
        }

        /// <summary>
        /// 切换服务器到正常运行状态
        /// </summary>
        public static void TurnToRunning()
        {
            if (_serverStatus == ServerStatus.Maintaining)
            {
                _serverStatus = ServerStatus.Running;
                _statusDesc = "服务器正常运行";
            }
            else
                throw new BaseException("服务器当前不处于维护状态，不允许切换到正常运行状态！");
        }

        /// <summary>
        /// 切换服务器到维护状态
        /// </summary>
        /// <param name="info">提示信息。为空时显示“系统正在升级维护，请稍候 …”</param>
        public static void TurnToMaintaining(string info)
        {
            if (_serverStatus == ServerStatus.Running)
            {
                _serverStatus = ServerStatus.Maintaining;
                _statusDesc = !string.IsNullOrEmpty(info) ? info : "系统正在升级维护，请稍候 …";
            }
            else
                throw new BaseException("服务器当前不处于正常运行状态，不允许切换到维护状态！");
        }

        public void SetSecurityToken(string securityToken, object tag)
        {
            SetSecurityToken(new ContextToken(securityToken, tag));
        }

        #endregion

        #region Internal

        internal void SetSecurityToken(ContextToken token)
        {
            // 缓存实时服务器句柄
            if (Context != null)
                Context.Session[SERVER_HANDLE_KEY] = ServerHandle;
            if (ApplicationContext != null)
                ApplicationContext[SERVER_HANDLE_KEY] = ServerHandle;

            Model.User user = null;
            if (token != null)
            {
                if (token.SecurityToken == APPROLE_SECURITY_TOKEN)
                {
                    var TruthOrganization = ServerApplication.User != null ? ServerApplication.User.Organization : null;
                    ApproleUnderstudy = true;
                    user = _approle;
                    if (TruthOrganization != null) // 使用原有机构
                        user.Organization = TruthOrganization;
                }
                else if (token.SecurityToken == ADMIN_SECURITY_TOKEN)
                {
                    var TruthOrganization = ServerApplication.User != null ? ServerApplication.User.Organization : null;
                    AdminUnderstudy = true;
                    user = admin;
                    if (TruthOrganization != null) // 使用原有机构
                        user.Organization = TruthOrganization;
                }
                else
                {
                    string primeTag;
                    object puk;

                    LogonComponent logonComp = (LogonComponent)ServerApplication.ComponentFactory.Create<ILogonContract>();
                    logonComp.GetUserLoginInfo(token.SecurityToken, out primeTag, out puk);

                    this.InitPrimeTag(primeTag);

                    ApproleUnderstudy = false;
                    AdminUnderstudy = false;

                    user = ServerApplication.User;
                    if (user == null || user.IsApprole || IsGlobleAdmin(user))
                    {
                        var comp = ServerApplication.ComponentFactory.Create<IUserContract>();
                        user = comp.Get(puk);
                    }

                    _current.SetSessionValue(USER_SESSION_KEY, user);
                }
            }
            else
            {
                ApproleUnderstudy = false;
                AdminUnderstudy = false;
            }

            this.SetSessionValue(SystemResources.CONTEXT_TOKEN_SLOTNAME, token);

            if (Context != null)
            {
                Context.User = user;
            }
            if (ApplicationContext != null)
            {
                ApplicationContext.User = user;
            }
        }

        internal ContextToken GetSecurityToken()
        {
            object obj = this.GetSessionValue(SystemResources.CONTEXT_TOKEN_SLOTNAME);
            if (obj is ContextToken)
                return (ContextToken)obj;
            else
                return null;
        }

        internal void SetApproleUnderstudy(ApproleScope scope)
        {
            _approleScope = scope;

            if (scope != null)
                SetSecurityToken(new ContextToken(APPROLE_SECURITY_TOKEN));
        }

        internal void SetAdminUnderstudy(AdminScope scope)
        {
            _adminScope = scope;

            if (scope != null)
                SetSecurityToken(new ContextToken(ADMIN_SECURITY_TOKEN));
        }

        /// <summary>
        /// 初始化用户登陆区域（帐套）。帐套名称为空时，取默认的帐套。
        /// </summary>
        /// <param name="primeTag">帐套名称。为空时，取默认的帐套</param>
        /// <returns>返回登陆帐套名称</returns>
        internal string InitPrimeTag(string primeTag)
        {
            if (String.IsNullOrEmpty(primeTag))
                primeTag = GetDefaultPrimeTag();

            this.SetSessionValue(USER_PRIME_TAG_KEY, primeTag);

            return primeTag;
        }

        /// <summary>
        /// 取默认的登陆区域（帐套）
        /// </summary>
        /// <returns></returns>
        internal string GetDefaultPrimeTag()
        {
            //string[] names = ApplicationSetting.GetConnectionStringNames(false);
            //if (names.Length != 0)
            //    return names[0];

            //return null;

            return ApplicationSetting.GetDefaultConnectionStringName();
        }

        /// <summary>
        /// 销毁当前用户的登陆区域（帐套）
        /// </summary>
        internal void DisposePrimeTag()
        {
            this.SetSessionValue(USER_PRIME_TAG_KEY, string.Empty);
        }

        /// <summary>
        /// 判断用户句柄与服务句柄是否一致
        /// </summary>
        /// <returns></returns>
        internal static bool IsSameHandle()
        {
            // 用户句柄与服务句柄一致
            return (Context != null &&
                    Context.Session != null &&
                    Context.Session[SERVER_HANDLE_KEY] != null &&
                    (string)Context.Session[SERVER_HANDLE_KEY] == ServerHandle)
                    ||
                    (ApplicationContext != null &&
                    ApplicationContext[SERVER_HANDLE_KEY] != null &&
                    (string)ApplicationContext[SERVER_HANDLE_KEY] == ServerHandle);
        }

        /// <summary>
        /// 判断当前用户是否全局管理员用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        internal static bool IsGlobleAdmin(User user)
        {
            //ContextToken token = _current != null && _current.GetSessionValue(SystemResources.CONTEXT_TOKEN_SLOTNAME) is ContextToken ? _current.GetSessionValue(SystemResources.CONTEXT_TOKEN_SLOTNAME) as ContextToken : null;
            ContextToken token = _current != null ? _current.GetSessionValue(SystemResources.CONTEXT_TOKEN_SLOTNAME) as ContextToken : null;
            return user != null && string.Compare(user.UserName, SystemResources.ADMINISTRATOR_NAME) == 0 && token != null && string.Compare(token.SecurityToken, ADMIN_SECURITY_TOKEN) == 0;
        }

        const string defaultConnectionProviderKey = "defaultProvider";
        static Dictionary<string, string> defaultConnectionProviderSettings = null;
        internal static IDbConnectionProvider DefaultConnectionProvider()
        {
            if (defaultConnectionProviderSettings == null)
            {
                defaultConnectionProviderSettings = new Dictionary<string, string>();
                var defaultConn = ApplicationSetting.GetDefaultConnectionStringName();
                var settings = ApplicationSetting.GetConnectionStringSettings(defaultConn);
                if (settings == null) throw new ArgumentNullException(string.Format("系统中不存在命名连接字符串“{0}”", defaultConn));

                defaultConnectionProviderSettings.Add("Key", defaultConnectionProviderKey);
                defaultConnectionProviderSettings.Add("ConnectionString", settings.ConnectionString);
                defaultConnectionProviderSettings.Add("ProviderName", settings.ProviderName);
                defaultConnectionProviderSettings.Add("DialectClass", ApplicationSetting.GetDefaultConnectionDialect());
            }

            return BaseFramework.ConnectionProvider.ConnectionProviderFactory.Instance.Create(defaultConnectionProviderKey, defaultConnectionProviderSettings);
        }

        #endregion

        #region Write DB Log...

        /// <summary>
        /// 写入系统日志
        /// </summary>
        /// <param name="source">日志源（如，用户管理、付款管理）</param>
        /// <param name="type">日志类型</param>
        /// <param name="msg">日志描述</param>
        public static void WriteLog(string source, LogType type, string msg)
        {
            WriteLog(source, type, msg, null);
        }

        /// <summary>
        /// 写入系统日志
        /// </summary>
        /// <param name="source">日志源（如，用户管理、付款管理）</param>
        /// <param name="type">日志类型</param>
        /// <param name="msg">日志描述</param>
        /// <param name="ex">异常</param>
        public static void WriteLog(string source, LogType type, string msg, Exception ex)
        {
            string organ = "-";
            string user = "-";
            if (User != null)
            {
                if (User.Organization != null)
                    organ = string.Format("{0}({1})", User.Organization.Name, User.Organization.Id);
                user = User.RealName;
            }

            // 获取格式化的日志信息
            msg = EncodingLogMsg(new LogMsg(Current != null ? Current.TrueUser : null,
                                            SystemResources.Host_IP,
                                            source,
                                            msg));

            switch (type)
            {
                case LogType.Info:
                    Logger.Info(msg, ex);
                    break;
                case LogType.Warn:
                    Logger.Warn(msg, ex);
                    break;
                case LogType.Error:
                    Logger.Error(msg, ex);
                    break;
                case LogType.Fatal:
                    Logger.Fatal(msg, ex);
                    break;
                default:
                    break;
            }
        }

        internal static LogMsg DecodingLogMsg(string msg)
        {
            LogMsg model = new LogMsg(msg);

            if (!string.IsNullOrEmpty(msg))
            {
                // 示例： 用户管理$#$总部$#$[121.213.12.78] 新增用户
                string[] infos = msg.Split(new string[] { SystemResources.SplitChar }, StringSplitOptions.None);
                if (infos.Length == 21)
                {
                    model.CompanyId = ObjectHelper.Convert<Guid>(infos[1], Guid.Empty);         // :1
                    model.OrganizationId = ObjectHelper.Convert<int?>(infos[2], null);   // :2
                    model.UserID = ObjectHelper.Convert<int?>(infos[3], null);           // :3
                    model.Source = infos[4];            // :4
                    model.CompanyName = infos[5];       // :5
                    model.OrganizationName = infos[6];  // :6
                    model.UserName = infos[7];          // :7
                    model.RealName = infos[8];          // :8
                    // ...
                    model.HostInfo = infos[19];         // :19
                    model.LogInfo = infos[20];          // :20
                }
            }

            return model;
        }

        internal static string EncodingLogMsg(LogMsg messModel)
        {
            if (messModel == null)
                return null;
            //           1      2      3      4      5          6        　7        8          9   10  11  12  13  14  15  16  17  18  19                20
            // 示例： $#$公司$#$网点$#$用户$#$模块$#$公司名称$#$网点名称$#$用户名$#$用户姓名$#$-$#$-$#$-$#$-$#$-$#$-$#$-$#$-$#$-$#$-$#$[121.213.12.78]$#$日志信息
            return string.Format("{0}{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}{0}{7}{0}{8}{0}{9}{0}{10}{0}{11}{0}{12}{0}{13}{0}{14}{0}{15}{0}{16}{0}{17}{0}{18}{0}{19}{0}{20}",
                                        SystemResources.SplitChar,  // :0
                                        messModel.CompanyId,        // :1
                                        messModel.OrganizationId,   // :2
                                        messModel.UserID,           // :3
                                        messModel.Source,           // :4
                                        messModel.CompanyName,      // :5
                                        messModel.OrganizationName, // :6
                                        messModel.UserName,         // :7
                                        messModel.RealName,         // :8
                                        string.Empty,               // :9
                                        string.Empty,               // :10
                                        string.Empty,               // :11
                                        string.Empty,               // :12
                                        string.Empty,               // :13
                                        string.Empty,               // :14
                                        string.Empty,               // :15
                                        string.Empty,               // :16
                                        string.Empty,               // :17
                                        string.Empty,               // :18
                                        messModel.HostInfo,         // :19
                                        messModel.LogInfo           // :20
                                        );
        }

        internal class LogMsg
        {
            Guid _companyID = Guid.Empty;
            int? _organizationID = null;
            int? _userID = null;
            string _companyName = null;
            string _organizationName = null;
            string _userName = null;
            string _realName = null;
            string _hostInfo = null;
            string _source = null;
            string _logInfo = null;

            public LogMsg(string log)
            {
                this.LogInfo = log;
            }

            public LogMsg(User user, string hostInfo, string source, string log)
            {
                this.Source = source;
                if (user != null)
                {
                    this.UserID = user.ID;
                    this.UserName = user.UserName;
                    this.RealName = user.RealName;
                    this.CompanyId = user.CompanyId;
                    this.OrganizationId = user.Organization != null ? user.Organization.Id : int.MinValue;

                    this.CompanyName = user.CompanyName;
                    this.OrganizationName = user.Organization != null ? user.Organization.ToString() : null;
                }
                this.HostInfo = hostInfo;
                this.LogInfo = log;
            }

            /// <summary>
            /// 公司
            /// </summary>
            public Guid CompanyId
            {
                get { return this._companyID; }
                set { this._companyID = value; }
            }


            /// <summary>
            /// 网点
            /// </summary>
            public int? OrganizationId
            {
                get { return this._organizationID; }
                set { this._organizationID = value; }
            }

            /// <summary>
            /// 用户
            /// </summary>
            public int? UserID
            {
                get { return this._userID; }
                set { this._userID = value; }
            }

            /// <summary>
            /// 所属公司
            /// </summary>
            public string CompanyName
            {
                get { return this._companyName; }
                set { this._companyName = value; }
            }

            /// <summary>
            /// 所属网点
            /// </summary>
            public string OrganizationName
            {
                get { return this._organizationName; }
                set { this._organizationName = value; }
            }

            /// <summary>
            /// 用户登陆名
            /// </summary>
            public string UserName
            {
                get { return this._userName; }
                set { this._userName = value; }
            }

            /// <summary>
            /// 用户姓名
            /// </summary>
            public string RealName
            {
                get { return this._realName; }
                set { this._realName = value; }
            }

            /// <summary>
            /// 客户端信息
            /// </summary>
            public string HostInfo
            {
                get { return this._hostInfo; }
                set { this._hostInfo = value; }
            }

            /// <summary>
            /// 功能模块
            /// </summary>
            public string Source
            {
                get { return this._source; }
                set { this._source = value; }
            }

            /// <summary>
            /// 日志信息
            /// </summary>
            public string LogInfo
            {
                get { return this._logInfo; }
                set { this._logInfo = value; }
            }
        }

        #endregion

        #region Private

        /// <summary>
        /// 是否已初始化
        /// </summary>
        /// <returns></returns>
        private static bool IsInitialized()
        {
            return (_current._factory != null && _current._logger != null);
        }

        /// <summary>
        /// 获取当前请求上下文用户（可能不是当前实际登陆用户）
        /// </summary>
        /// <returns></returns>
        private static User GetContextUser()
        {
            if (_current.ApproleUnderstudy)
            {
                return _approle;
            }
            else if (_current.AdminUnderstudy)
            {
                return admin;
            }
            else if (IsSameHandle())
            {
                if (_current.GetSessionValue(USER_SESSION_KEY) != null)
                {
                    return _current.GetSessionValue(USER_SESSION_KEY) as User;
                }
                else if (Context != null && Context.User != null)
                {
                    return Context.User as User;
                }
                else if (ApplicationContext.Current != null && ApplicationContext.User != null)
                {
                    return ApplicationContext.User;
                }
            }

            return null;
        }

        /// <summary>
        /// 应用程序身份
        /// </summary>
        private bool ApproleUnderstudy
        {
            get
            {
                object obj = this.GetSessionValue(IS_APPROLE_UNDERSTUDY_KEY);
                return (obj != null && (bool)obj);
            }
            set
            {
                this.SetSessionValue(IS_APPROLE_UNDERSTUDY_KEY, value);
            }
        }

        /// <summary>
        /// 超级管理员身份
        /// </summary>
        private bool AdminUnderstudy
        {
            get
            {
                object obj = this.GetSessionValue(IS_ADMIN_UNDERSTUDY_KEY);
                return (obj != null && (bool)obj);
            }
            set
            {
                this.SetSessionValue(IS_ADMIN_UNDERSTUDY_KEY, value);
            }
        }

        private object GetSessionValue(string name)
        {
            if (Context != null && Context.Session != null)
            {
                return Context.Session[name];
            }
            else if (ApplicationContext != null)
            {
                return ApplicationContext[name];
            }
            else
            {
                //LocalDataStoreSlot slot = Thread.GetNamedDataSlot(name);
                //if (slot != null)
                //    return Thread.GetData(slot);

                return CallContext.GetData(name);
            }
        }

        private void SetSessionValue(string name, object value)
        {
            if (!String.IsNullOrEmpty(name))
            {
                if (Context != null && Context.Session != null)
                {
                    if (value != null)
                        Context.Session[name] = value;
                    else
                        Context.Session.Remove(name);
                }
                else if (ApplicationContext != null)
                {
                    if (value != null)
                        ApplicationContext[name] = value;
                    else
                        ApplicationContext.Remove(name);
                }
                else
                {
                    //LocalDataStoreSlot slot = Thread.GetNamedDataSlot(name);
                    //if (slot != null)
                    //    Thread.SetData(slot, value);

                    if (value != null)
                        CallContext.SetData(name, value);
                    else
                        CallContext.FreeNamedDataSlot(name);
                }
            }
        }

        #endregion
    }

    /// <summary>
    /// 参考：
    /// http://www.pin5i.com/showtopic-27165.html
    /// </summary>
    [Serializable]
    public sealed class ApplicationContext : ILogicalThreadAffinative
    {
        public const string ContextKey = "b2917b14-b21f-493e-9787-d1cf3454e171";
        private readonly Hashtable _session;


        public ApplicationContext(string serverHandle)
        {
            _session = new Hashtable();
            _session.Add("SERVER_HANDLE_KEY", serverHandle);
        }

        public object this[string key]
        {
            get { return _session[key]; }
            set { _session[key] = value; }
        }

        public void Remove(string key)
        {
            _session.Remove(key);
        }

        [ThreadStatic]
        public static ApplicationContext _applicationContext = null;
        public static ApplicationContext Current
        {
            get
            {
                if (HttpContext.Current != null)
                {
                    if (HttpContext.Current.Session[ContextKey] == null) HttpContext.Current.Session[ContextKey] = new ApplicationContext(ServerApplication.ServerHandle);
                    return HttpContext.Current.Session[ContextKey] as ApplicationContext;
                }

                if (_applicationContext == null) _applicationContext = new ApplicationContext(ServerApplication.ServerHandle);
                return _applicationContext;

                //var context = new ApplicationContext(ServerApplication.ServerHandle);
                //if (CallContext.GetData(ContextKey) == null) CallContext.LogicalSetData(ContextKey, context);
                //return CallContext.GetData(ContextKey) as ApplicationContext;
            }
        }
        public static void SetSessionValue(string key, object value)
        {
            if (!String.IsNullOrEmpty(key))
            {
                if (Context != null && Context.Session != null)
                {
                    if (value != null)
                        Context.Session[key] = value;
                    else
                        Context.Session.Remove(key);
                }
                else
                {
                    if (value != null)
                        CallContext.SetData(key, value);
                    else
                        CallContext.FreeNamedDataSlot(key);
                }
            }
        }

        public static object GetSessionValue(string key)
        {
            if (!String.IsNullOrEmpty(key))
            {
                if (Context != null && Context.Session != null)
                    return Context.Session[key];
                else
                    return CallContext.GetData(key);
            }

            return null;
        }

        //[ThreadStatic]
        //private static HttpContext _context;

        /// <summary>
        /// 请求上下文
        /// </summary>
        private static HttpContext Context
        {
            get
            {
                if (HttpContext.Current != null)
                {
                    return HttpContext.Current;
                }
                //else
                //{
                //    if (_context == null)
                //    {
                //        try
                //        {

                //            TextWriter tw = new StringWriter();
                //            HttpWorkerRequest wr = new SimpleWorkerRequest("default.html", "", tw);
                //            _context = new HttpContext(wr);
                //            HttpContext.Current = _context;
                //            //CallContext.LogicalSetData(ContextKey, _context);
                //        }
                //        catch { return null; }
                //    }

                //    return _context;
                //}

                return null;
            }
        }

        public User User
        {
            get
            {
                ApplicationContext current = ApplicationContext.Current;
                return current[ContextKey + "_User"] as User;
            }
            set
            {
                ApplicationContext current = ApplicationContext.Current;
                current[ContextKey + "_User"] = value;
            }
        }

        public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            throw new NotImplementedException();
        }
    }
}